package org.javahispano.javacup.tacticas_aceptadas.sjvc;
import org.javahispano.javacup.modelo.*;

public class Situaciones {
	
	public static double ObtenerFuerzaParaGolpear(SituacionPartido sp, int jugador, Posicion destinoBalon, boolean balonAlto){
		
		double distanciaAlDestino = sp.misJugadores()[jugador].distancia(destinoBalon);
		double factor_dismin_vel = balonAlto ? Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE : Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
		
		//Vamos a calcular la fuerza realizando las operaciones inversas que realiza el framework
		//para mover el bal�n en funci�n de la velocidad y el factor de disminuci�n de velocidad
		double velocidad = 0.75;
		
		do
		{
			velocidad = velocidad / factor_dismin_vel; //Aumentamos la velocidad
			distanciaAlDestino -= velocidad; //Acortamos la distancia	
		}
		while(distanciaAlDestino > 0);
		
		//Si el tiro no va por el suelo, necesitamos m�s velocidad (parte de la velocidad va para el eje Z)
		if(balonAlto){
			double anguloVertical = balonAlto ? Constantes.ANGULO_VERTICAL : 0;
			double angConvert = Math.PI / 180d;
			anguloVertical = anguloVertical * angConvert;
		    if(Math.cos(anguloVertical) > 0)
				velocidad = velocidad / Math.cos(anguloVertical);
		}
		
		double fuerza = velocidad / Constantes.getVelocidadRemate(sp.detalleMisJugadores()[jugador].getRemate());
		
		return fuerza;
	}
	
	public static double MaximaDistanciaGolpe(SituacionPartido sp, int indiceJugador, boolean balonAlto){
		double velocidad = Constantes.getVelocidadRemate(sp.detalleMisJugadores()[indiceJugador].getRemate());
		double factor_dismin_vel = balonAlto ? Constantes.FACTOR_DISMINUCION_VEL_BALON_AIRE : Constantes.FACTOR_DISMINUCION_VEL_BALON_SUELO;
		
		if(balonAlto){
			double anguloVertical = balonAlto ? Constantes.ANGULO_VERTICAL : 0;
			double angConvert = Math.PI / 180d;
			anguloVertical = anguloVertical * angConvert;
			velocidad = velocidad * Math.cos(anguloVertical);
		}
		
		double distancia = 0;
		while(velocidad > 0.1){
			distancia += velocidad;
			velocidad = velocidad * factor_dismin_vel;
		}
		
		return distancia;
	}
	
	public static Posicion[] TodosLosJugadores(SituacionPartido sp){
		Posicion[] posiciones = new Posicion[22];
		
		for(int i = 0; i<11;i++){
			posiciones[i] = sp.misJugadores()[i];
			posiciones[i+11] = sp.rivales()[i];
		}
		
		return posiciones;
	}
	
	public static boolean EstanCerca(Posicion p1, Posicion p2){
		return p1.distancia(p2) <= 1;
	}
	
	public static boolean HayAlguienCerca(SituacionPartido sp, Posicion p){
		Posicion[] jugadores = TodosLosJugadores(sp);
		return EstanCerca(p,jugadores[p.indiceMasCercano(jugadores)]);
	}
	
	//Comprueba si hay alg�n jugador (o m�s) entre dos jugadores m�os.
	public static boolean HayJugadoresEntreDosJugadoresPropios(SituacionPartido sp, int indiceJ1, int indiceJ2){

		//Obtengo la posici�n de los jugadores
		Posicion pj1 = sp.misJugadores()[indiceJ1];
		Posicion pj2 = sp.misJugadores()[indiceJ2];
		
		//Obtengo el �ngulo que hay entre los dos puntos
		double anguloJ1_J2 = pj1.angulo(pj2);
	
		//Compruebo si el �ngulo de pj1 a alguno de los otros jugadores es igual al �ngulo obtenido
		//Y adem�s que la distancia de pj1 a pji sea mayor que la distancia de pj1 a pj2
		Posicion[] todosLosJugadores = TodosLosJugadores(sp);
		for(int i=0;i<todosLosJugadores.length;i++)
			if(i!=indiceJ1 && i!=indiceJ2 && pj1.distancia(todosLosJugadores[i]) < pj1.distancia(pj2))
			{
				double anguloJ1_Ji = pj1.angulo(todosLosJugadores[i]);
				if(anguloJ1_Ji <= anguloJ1_J2 + 3 && anguloJ1_Ji >= anguloJ1_J2 - 3)
					return true;
			}
		
		return false;
	}
	
	public static boolean HayRivalesEntreDosPosiciones(SituacionPartido sp, Posicion p1, Posicion p2){
		//Obtengo el �ngulo que hay entre los dos puntos
		double anguloJ1_J2 = p1.angulo(p2);
	
		//Compruebo si el �ngulo de pj1 a alguno de los otros jugadores es igual al �ngulo obtenido
		//Y adem�s que la distancia de pj1 a pji sea mayor que la distancia de pj1 a pj2
		Posicion[] todosLosJugadores = sp.rivales();
		for(int i=0;i<todosLosJugadores.length;i++)
			if(p1.distancia(todosLosJugadores[i]) < p1.distancia(p2))
			{
				double anguloJ1_Ji = p1.angulo(todosLosJugadores[i]);
				if(anguloJ1_Ji <= anguloJ1_J2 + 1 && anguloJ1_Ji >= anguloJ1_J2 - 1)
					return true;
			}
		
		return false;
	}
}